#pragma once

#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <cerrno>
#include <unistd.h>
#include <fcntl.h>

const std::string comm_path = "./myfifo"; // 创建公共路径,供两个毫不相干的文件使用
#define DefaultFd -1
#define Creater 1
#define User 2
// 设置读写:
#define Read O_RDONLY
#define Write O_WRONLY

#define BaseSize 4096

// 用类实现
class NamePipe
{
private:
    bool OpenNmaePipe(int mode)
    {
        _fd = open(_fifo_path.c_str(), mode);
        if (_fd < 0)
        {
            return false;
        }

        return true;
    }

public:
    // 创建者才需要建立管道，否则就什么都不需要做

    NamePipe(const std::string &path, int who) : _fifo_path(path), _id(who), _fd(DefaultFd)
    {
        if (_id == Creater)
        {
            int res = mkfifo(_fifo_path.c_str(), 0666);
            if (res != 0) // 0成功
            {
                perror("mkfifo");
            }
            std::cout << "Creater create named pipe" << std::endl;
        }
    }

    bool OpenForRead()
    {
        return OpenNmaePipe(Read);
    }

    bool OpenForWrite()
    {
        return OpenNmaePipe(Write);
    }

    // 规范：输入型参数： const&
    // 输出型 *         输入输出型 &
    int ReadNamePipe(std::string *out)
    {
        char buffer[BaseSize];
        int n = read(_fd, buffer, sizeof(buffer));
        if (n > 0)
        {
            buffer[n] = 0;
            *out = buffer;
        }
        return n;
    }
    int WriteNamePipe(const std::string &in)
    {
        return write(_fd,in.c_str(),in.size());
    }

    ~NamePipe()
    {
        // sleep(5);
        if (_id == Creater)
        {
            int res = unlink(_fifo_path.c_str()); // 成功返回0失败返回-1
            if (res != 0)                         // 0成功
            {
                perror("unlink");
            }
            std::cout << "Creater free named fifd" << std::endl;
        }
        if (_fd != DefaultFd)
        {
            close(_fd);
        }
    }

private:
    const std::string _fifo_path;
    int _id;
    int _fd;
};
